from datetime import datetime,UTC
import happybase

FAMILIES = {
    'basic': dict(),      # 订单基本信息
    'shipping': dict(),   # 物流信息
    'payment': dict(),    # 支付信息
    'status': dict(),     # 状态信息
} # 基本列族设计
FIELD_NAME_MAPPING = {
    'order_id': '订单编号',
    'user_id': '用户ID',
    'product_name': '商品名称',
    'quantity': '数量',
    'price': '单价',
    'create_time': '创建时间',
    'address': '收货地址',
    'receiver_name': '收件人',
    'phone': '联系电话',
    'city': '城市',
    'zipcode': '邮编',
    'tracking_no': '物流单号',
    'payment_method': '支付方式',
    'amount': '支付金额',
    'pay_time': '支付时间',
    'transaction_id': '交易流水号',
    'status': '支付状态',
    'current_status': '当前状态',
    'last_updated': '最后更新时间',
    'remark': '备注'
} # 添加字段名到中文的映射
TABLE_NAME = 'etailer_orders' # 业务表表名
HOST_HBASE = '192.168.100.136' # 服务器ip
PORT_HBASE = 9090   # hbase服务映射端口号

def get_connection():
    """
    获取hbase连接池对象

    :return:
    """

    connection = happybase.Connection(
        host=HOST_HBASE,
        port=PORT_HBASE,
        timeout=5000,  # 超时（毫秒）
        autoconnect=True  # 是否自动连接
    )
    return connection

def create_table(connection_hbase, table_name):
    """
    根据业务建表创建表

    :param connection_hbase: hbase连接池对象
    :param table_name: 预设表名
    :return:
    """

    # 创建表
    my_table = table_name

    if my_table.encode() not in connection_hbase.tables():
        connection_hbase.create_table(my_table, FAMILIES)
        print(f"表 '{my_table}' 创建成功！")
    else:
        print(f"表 '{my_table}' 已存在。")

    # 如果表不存在，则创建
    if my_table.encode() not in connection_hbase.tables():
        connection_hbase.create_table(my_table, FAMILIES)
        print(f"表 '{my_table}' 创建成功！")

def insert_order(table_hbase, order_id, user_id, product_name, quantity, price, create_time,
                 address=None, receiver_name=None, phone=None, city=None, zipcode=None, tracking_no=None,
                 payment_method=None, amount=None, pay_time=None, transaction_id=None, status=None,
                 current_status=None, last_updated=None, remark=None):
    """
    根据字段添加表数据

    :param table_hbase: 表名
    :param order_id: 订单编号
    :param user_id: 用户编号
    :param product_name: 商品名
    :param quantity: 数量
    :param price: 价格
    :param create_time: 创建时间
    :param address: 收货地址
    :param receiver_name: 收件人
    :param phone: 联系电话
    :param city: 城市
    :param zipcode: 邮编
    :param tracking_no: 物流单号
    :param payment_method: 支付方式
    :param amount: 支付金额
    :param pay_time: 支付时间
    :param transaction_id: 交易流水号
    :param status: 当前状态
    :param current_status:
    :param last_updated: 最后更新时间
    :param remark: 备注
    """

    # 基本信息
    basic_data = {
        'order_id': order_id,
        'user_id': user_id,
        'product_name': product_name,
        'quantity': str(quantity),
        'price': str(price),
        'create_time': create_time
    }

    # 物流信息（只有已发货或待发货才填）
    shipping_data = {}
    if address:
        shipping_data.update({
            'address': address,
            'receiver_name': receiver_name,
            'phone': phone,
            'city': city,
            'zipcode': zipcode,
            'tracking_no': tracking_no or ''
        })

    # 支付信息（只有已付款才填）
    payment_data = {}
    if payment_method:
        payment_data.update({
            'payment_method': payment_method,
            'amount': str(amount),
            'pay_time': pay_time,
            'transaction_id': transaction_id,
            'status': status or 'SUCCESS'
        })

    # 状态信息
    status_data = {
        'current_status': current_status,
        'last_updated': last_updated,
        'remark': remark or ''
    }

    # 插入数据（批量写入）
    row_key = order_id
    data = {}
    for cf, values in [('basic', basic_data), ('shipping', shipping_data), ('payment', payment_data), ('status', status_data)]:
        for key, val in values.items():
            data[f'{cf}:{key}'] = val

    table_hbase.put(row_key, data)
    print(f"订单 {order_id} 插入成功！")

def update_order_status(table_hbase, order_id, new_status, remark, last_updated=None, tracking_no = None):
    """
    更新订单状态（覆盖旧状态）

    :param tracking_no: 物流单号
    :param table_hbase: 表名
    :param order_id: 订单编号
    :param new_status: 订单新状态
    :param remark: 备注
    :param last_updated: 更新时间
    :return:
    """

    if last_updated is None:
        last_updated = datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ')

    status_data = {
        'status:current_status': new_status,
        'status:last_updated': last_updated,
        'status:remark': remark
    }

    table_hbase.put(order_id, status_data)

    if tracking_no:
        table_hbase.put(order_id, {'payment:tracking_no': tracking_no})

    print(f" 订单 {order_id} 状态已更新为: {new_status}")

def print_formatted_orders(table_hbase):
    """
    格式化获取表全部数据

    :param table_hbase: 表名
    :return:
    """
    print("\n=== 所有订单信息 ===")
    for key, data in table_hbase.scan():
        order_id = key.decode('utf-8')
        print(f"\n订单编号: {order_id}")
        print("=" * 50)

        # 按照列族组织数据
        organized_data = {'basic': {}, 'shipping': {}, 'payment': {}, 'status': {}}

        for column, value in data.items():
            column_str = column.decode('utf-8')
            value_str = value.decode('utf-8')

            cf, field = column_str.split(':', 1)
            if cf in organized_data:
                organized_data[cf][field] = value_str

        # 使用中文标签打印各部分内容
        section_names = {
            'basic': '基本信息',
            'shipping': '物流信息',
            'payment': '支付信息',
            'status': '状态信息'
        }

        for cf, cf_name in section_names.items():
            if organized_data[cf]:
                print(f"\n{cf_name}:")
                for field, value in organized_data[cf].items():
                    chinese_field = FIELD_NAME_MAPPING.get(field, field)  # 获取中文字段名，默认为原字段名
                    print(f"  {chinese_field}: {value}")

def cancel_order(table_hbase, order_id, reason=''):
    """
    取消订单 - 删除订单相关数据

    :param table_hbase: 表名
    :param order_id: 订单编号
    :param reason: 原因
    :return:
    """

    try:
        # 首先检查订单是否存在
        row = table_hbase.row(order_id)
        if not row:
            print(f"订单 {order_id} 不存在，无法取消")
            return False

        # 更新订单状态为已取消
        current_time = datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ')

        cancel_data = {
            'status:current_status': 'CANCELLED',
            'status:last_updated': current_time,
            'status:remark': reason
        }

        table_hbase.put(order_id, cancel_data)
        print(f"订单 {order_id} 已成功取消，原因: {reason}")
        return True

    except Exception as e:
        print(f"取消订单 {order_id} 失败: {str(e)}")
        return False

def delete_table(conn, table_hbase, force_status=True):
    """
    删除表

    :param force_status: 强制删除，默认true
    :param conn: 连接对象
    :param table_hbase: 表名
    :return:
    """

    if table_hbase in conn.tables():
        conn.delete_table(table_hbase, force=force_status)

def start_my_happybase():
    """程序入口"""

    # 显式连接
    conn = get_connection()
    conn.open()

    # 初始化，先检测系统是否存在预设订单表，有则删除
    delete_table(conn, TABLE_NAME, True)

    create_table(conn, TABLE_NAME)

    # 获取表对象
    table = conn.table(TABLE_NAME)

    """插入三个不同状态的订单"""
    # 订单 1：待付款状态
    insert_order(
        table_hbase=table,
        order_id='ORD20240501001',
        user_id='u1001',
        product_name='iPhone 15 Pro',
        quantity=1,
        price=8999.00,
        create_time='2024-05-01T10:00:00Z',
        current_status='PENDING_PAYMENT',
        last_updated='2024-05-01T10:00:00Z',
        remark='等待用户支付'
    )

    # 订单 2：已付款待发货状态
    insert_order(
        table_hbase=table,
        order_id='ORD20240501002',
        user_id='u1002',
        product_name='MacBook Air M2',
        quantity=1,
        price=8499.00,
        create_time='2024-05-01T11:00:00Z',
        address='上海市浦东新区张江高科路100号',
        receiver_name='李四',
        phone='13900139000',
        city='上海',
        zipcode='201200',
        tracking_no='',  # 尚未发货，暂无物流单号
        payment_method='wechat',
        amount=8499.00,
        pay_time='2024-05-01T11:15:00Z',
        transaction_id='TXN20240501002',
        status='SUCCESS',
        current_status='PAID_WAITING_SHIPMENT',
        last_updated='2024-05-01T11:15:00Z',
        remark='已支付，等待仓库发货'
    )

    # 订单 3：已发货状态
    insert_order(
        table_hbase=table,
        order_id='ORD20240501003',
        user_id='u1003',
        product_name='AirPods Pro',
        quantity=2,
        price=1998.00,
        create_time='2024-05-01T12:00:00Z',
        address='深圳市南山区科技园北区1栋',
        receiver_name='王五',
        phone='13700137000',
        city='深圳',
        zipcode='518000',
        tracking_no='SF123456789',
        payment_method='alipay',
        amount=1998.00,
        pay_time='2024-05-01T12:10:00Z',
        transaction_id='TXN20240501003',
        status='SUCCESS',
        current_status='SHIPPED',
        last_updated='2024-05-01T12:30:00Z',
        remark='已发货，快递单号：SF123456789'
    )

    print("所有订单插入完成！")

    """订单状态变更"""
    # 1. 订单1：从 PENDING_PAYMENT → PAID_WAITING_SHIPMENT
    update_order_status(
        table_hbase=table,
        order_id='ORD20240501001',
        new_status='PAID_WAITING_SHIPMENT',
        remark='用户完成支付，进入待发货流程',
        last_updated='2024-05-01T10:30:00Z'
    )

    # 2. 订单2：从 PAID_WAITING_SHIPMENT → SHIPPED（同时补充物流单号）
    # 先更新状态
    update_order_status(
        table_hbase=table,
        order_id='ORD20240501002',
        new_status='SHIPPED',
        remark='仓库已发货，物流单号：SF987654321',
        last_updated='2024-05-01T14:00:00Z',
        tracking_no='SF987654321'
    )

    print_formatted_orders(table)  # 获取指定表全部数据

    print()

    cancel_order(table_hbase=table, order_id='ORD20240501003', reason="不想要了")

    print_formatted_orders(table)  # 获取指定表全部数据

    # TODO
    """
    条件查询部分
    1.查询指定订单的完整信息
    2.只查询订单的物流信息
    3.只查询订单的支付信息
    4.查看所有订单的基本信息
    5.运营需要分析2025年10月1日这一天的所有订单情况。
    6.数据库管理员需要进行数据备份，只需要备份订单的核心信息（basic列族）和状态信息（status列族）。
    7.客服接到用户反馈，需要查找所有备注中包含"优先"或"加急"字样的订单。
    8.找出用户user002在2025年10月1日之后创建的、金额在100-300元之间的所有订单。
    """

    # 关闭连接
    conn.close()

if __name__ == '__main__':
    start_my_happybase()